﻿
using System;
using System.Web.Mvc;
using System.Web.Routing;
using Microsoft.Practices.Unity;
using Oxite.Infrastructure;
using Oxite.Configuration;
using ECube.SEC.FormsAuthentication.Controllers;
//using ECube.SEC.FormsAuthentication.Extensions;
using ECube.SEC.FormsAuthentication.Models;
using ECube.SEC.FormsAuthentication.Services;
using ECube.SEC.Membership.Filters;
using ECube.SEC.Membership.Services;
using Oxite.Validation;

namespace ECube.SEC.FormsAuthentication
{
    public class FormsAuthenticationModule : IOxiteAuthenticationModule
    {
        private readonly IUnityContainer container;

        public FormsAuthenticationModule(IUnityContainer container)
        {
            this.container = container;
        }

        #region IOxiteModule Members

        public void Initialize(OxiteModuleConfigurationElement module)
        {
        }

        public void Unload()
        {
        }

        public void RegisterRoutes(RouteCollection routes)
        {
            string[] controllerNamespaces = new string[] { "ECube.SEC.FormsAuthentication.Controllers" };

            routes.MapRoute(
                "SignIn",
                "SignIn",
                new { controller = "User", action = "SignIn", AllowAnonymous=true },
                null,
                controllerNamespaces
                );

            routes.MapRoute(
                "SignOut",
                "SignOut",
                new { controller = "User", action = "SignOut", AllowAnonymous = true },
                null,
                controllerNamespaces
                );
            routes.MapRoute(
                "Register",
                "Register/{domain}",
                new { controller = "User", action = "Register",domain=UrlParameter.Optional, AllowAnonymous = true },
                null,
                controllerNamespaces
                );
            routes.MapRoute(
                "UserChangePassword",
                "Admin/Users/{userName}/ChangePassword",
                new { controller = "User", action = "ChangePassword", role = "Admin", validateAntiForgeryToken = true },
                null,
                controllerNamespaces
                );
        }

        public void RegisterCatchAllRoutes(RouteCollection routes)
        {
        }

        public void RegisterFilters(IFilterRegistry filterRegistry)
        {
            ControllerActionFilterCriteria criteria = new ControllerActionFilterCriteria();

            criteria.AddMethod<UserController>(u => u.ChangePassword(null));
            criteria.AddMethod<UserController>(u => u.ChangePassword(null, null));
            
            filterRegistry.Add(new[] { criteria }, typeof(AuthorizationFilter));
        }

        public void RegisterModelBinders(ModelBinderDictionary modelBinders)
        {
          
        }

        public void RegisterWithContainer()
        {
            container
                .RegisterType<IFormsAuthenticationUserService, FormsAuthenticationUserService>()
                .RegisterType<IFormsAuthentication, FormsAuthenticationWrapper>();
        }

        #endregion

        #region IOxiteAuthenticationModule Members

        public IUser GetUser(RequestContext context)
        {
            IUserService userService = container.Resolve<IUserService>();

            if (context.HttpContext.User.Identity.IsAuthenticated)
                return userService.GetUser(context.HttpContext.User.Identity.Name);

            return new UserAnonymous();
        }

        public string GetRegisterUrl(RequestContext context)
        {
            UrlHelper urlHelper = new UrlHelper(context, container.Resolve<RouteCollection>());

            return urlHelper.RouteUrl("Register");
        }


        public string GetSignInUrl(RequestContext context)
        {
            UrlHelper urlHelper = new UrlHelper(context, container.Resolve<RouteCollection>());

            Uri referrer =  context.HttpContext.Request.UrlReferrer;

            if (referrer != null && urlHelper.RouteUrl("Register").Equals(referrer.AbsolutePath, StringComparison.OrdinalIgnoreCase))
            {
                return urlHelper.RouteUrl("SignIn");
            }

            string returnUrl = string.Compare(context.HttpContext.Request.HttpMethod, HttpVerbs.Get.ToString(), true) == 0 || referrer == null
                ? context.HttpContext.Request.Url.AbsolutePath
                : referrer.AbsolutePath;
            if (returnUrl.Equals(context.HttpContext.Request.ApplicationPath, StringComparison.OrdinalIgnoreCase) && !returnUrl.EndsWith("/"))
            { 
                returnUrl += "/"; 
            }

            return urlHelper.RouteUrl("SignIn", new { ReturnUrl = returnUrl });
        }

        public string GetSignOutUrl(RequestContext context)
        {
            UrlHelper urlHelper = new UrlHelper(context, container.Resolve<RouteCollection>());

            return urlHelper.RouteUrl("SignOut");
        }

        #endregion
    }
}
